+const Gi = imports._gi;
+
import {ExtensionBase, GettextWrapper} from './sharedInternals.js';
const {extensionManager} = imports.ui.main;
*/
overrideMethod(prototype, methodName, createOverrideFunc) {
const originalMethod = this._saveMethod(prototype, methodName);
- prototype[methodName] = createOverrideFunc(originalMethod);
+ this._installMethod(prototype, methodName, createOverrideFunc(originalMethod));
}
/**
if (originalMethod === undefined)
delete prototype[methodName];
else
- prototype[methodName] = originalMethod;
+ this._installMethod(prototype, methodName, originalMethod);
savedProtoMethods.delete(methodName);
if (savedProtoMethods.size === 0)
savedProtoMethods.set(methodName, originalMethod);
return originalMethod;
}
+
+ _installMethod(prototype, methodName, method) {
+ if (methodName.startsWith('vfunc_')) {
+ const giPrototype = prototype[Gi.gobject_prototype_symbol];
+ giPrototype[Gi.hook_up_vfunc_symbol](methodName.slice(6), method);
+ } else {
+ prototype[methodName] = method;
+ }
+ }
}
const JsUnit = imports.jsUnit;
+import GObject from 'gi://GObject';
+
import '../../js/ui/environment.js';
import {InjectionManager} from '../../js/extensions/extension.js';
}
}
+class GObject1 extends GObject.Object {
+ static [GObject.properties] = {
+ 'plonked': GObject.ParamSpec.boolean(
+ 'plonked', '', '',
+ GObject.ParamFlags.READWRITE,
+ false),
+ };
+
+ static {
+ GObject.registerClass(this);
+ }
+
+ plonk() {
+ this.set_property('plonked', true);
+ }
+}
+
/**
* @param {object} object to modify
*/
JsUnit.assertEquals(obj.getCount(), obj.count);
JsUnit.assert(obj.count > 0);
JsUnit.assertRaises(() => obj.getOtherNumber());
+
+// GObject injections
+const gobj = new GObject1();
+let vfuncCalled;
+
+injectionManager.overrideMethod(
+ GObject1.prototype, 'vfunc_set_property', originalMethod => {
+ return function (...args) {
+ // eslint-disable-next-line no-invalid-this
+ originalMethod.apply(this, args);
+ vfuncCalled = true;
+ };
+ });
+
+// gobj is now modified
+vfuncCalled = false;
+gobj.plonk();
+JsUnit.assertTrue(vfuncCalled);
+
+injectionManager.clear();
+
+// gobj is unmodified again
+vfuncCalled = false;
+gobj.plonk();
+JsUnit.assertFalse(vfuncCalled);